/* (PARI) R. J. Cano, Jun 19 2014; ...Dedicated to: Charles Greathouse IV and Joerg Arndt */

/* Implements the conversion from a GP matrix ("t_MAT") to a single GP list ("t_LIST")
*/
matx2Lst(M)={ 
  my(ans:list);
  ans=listcreate();
  for(i=1,#M[,1],
    for(j=1,#M[1,],
      listput(ans,M[i,j])
    )
  );
  ans
}

/* Makes a just-in-time offset correction.
*/
U(a,b)=if(b,b,a);

/* Check if [y,x] belongs or not to one of the diagonals for a squared matrix m*m.
 * 
 * ( Selectors: z=1 the main diagonal, z=0 the reversed diagonal )
*/
F(m,z,y,x)=if(z,(x==y),(m+1==x+y));

/* Implements the Steinhaus-Johnson-Trotter algorithm
 * returning the first "sum{k=1..n}(k!*k)" terms of A207324
 * in the form of a single GP list ("t_LIST").
 * 
 * When just=1 is used, it returns only the n-th matrix (n!*n items).
 * 
 * The completion algorithm indeed is pretty simple. And it is based
 * upon properly interpreted arithmetic and sieve patterns.
 * 
*/
A207324flattenedMatricesByRows(n,just=0)={
  my(z,m=1,q,r,t,B,a0:list,a1:list,a2:list);
  a0=matx2Lst(matrix(1,1,i,j,1));
  a2=listcreate();
  while(m<=n,if(m>1,
    B=matrix(m!,m);
    q=0;
    z=0;
    for(i=1,#B[,1],
      for(j=1,#B[1,],
	B[i,j]=m*F(m,z,U(m,i%m),j);
        q++;
      );
      if(q==m^2,q=0;z=!z);
    );
    a1=matx2Lst(B);
    r=0;
    t=1;
    for(u=1,(m-1)!,
      r++;
      for(v=1,m,
        for(p=(r-1)*(m-1)+1,r*(m-1),
	  while(a1[t],t++);
	  a1[t]=a0[p];
        );
      );
    );
    a0=a1;
    );
  m++;
  for(k=1,#a0,listput(a2,a0[k]));
  );
  if(m==1,a0,if(just,a0,a2));
}

printPermutations(n)={
  my(Q=A207324flattenedMatricesByRows(n,1),u=0);
  for(i=1,n!,
    for(j=1,n,
        print1(Q[u++]);
    );
    print1("\n")
  )
}

/*
 * Bonus (commented below) For a b-file generation of A207324
 * Verified OK!, against the published original by using md5;
 * 
 * (Please remember to use: gp -q -f filename > output.txt,
 *  and remove the trailing newline ending the file
 *  before proceed the md5 comparison)
*/

/* * /
Q=A207324flattenedMatricesByRows(7);
for(l=1,10000,print(l" "Q[l]));
quit();
/ * */